import random

from django_redis import get_redis_connection
from django.db.models import F
from django.shortcuts import render, redirect

import settings
from web import models
from utils.pager import Pagination
from utils.BootStrapForm import BootStrapForm
from django import forms
from django.core.exceptions import ValidationError
import datetime
from utils.video import get_old_view_count
from django.conf import settings

from django.db import transaction
from django.contrib import messages
from django.conf import settings


def my_order_list(request):
    # 获取我的订单，为当前登录的用户
    queryset = models.Order.objects.filter(customer_id=request.wl_user.id, active=1).order_by('-id')
    paginator = Pagination(request, queryset)
    return render(request, 'my_order_list.html', {'paginator': paginator})


class MyOrderModelFormForm(BootStrapForm, forms.ModelForm):
    class Meta:
        model = models.Order
        fields = ['url', 'count']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # 取出价格策略
        queryset = models.PricePolicy.objects.all().order_by('count')
        price_count_list = []
        text_count_list = []
        for item in queryset:
            unit_price = item.price / item.count
            price_count_list.append([item.count, f"大于等于{item.count} 单价：¥{unit_price:.2f}/条", unit_price])
            text_count_list.append(f"大于等于{item.count} 单价：¥{unit_price:.2f}/条")

        if text_count_list:
            self.fields['count'].help_text = "、".join(text_count_list)
        else:
            self.fields['count'].help_text = "请联系管理员设置价格！"
        # 用于后续的校验
        self.price_count_list = price_count_list

    def clean_count(self):
        # 表单中提交的数量
        count = self.cleaned_data['count']
        if not self.price_count_list:
            raise ValidationError("请联系管理员设置价格！")

        # 数据库中的数量
        min_count_limit = self.price_count_list[0][0]
        if count < min_count_limit:
            raise ValidationError(f"最低支持的数量为{min_count_limit}")
        return count


def my_order_add(request):
    if request.method == 'GET':
        form = MyOrderModelFormForm()
        return render(request, 'form.html', {'form': form})

    form = MyOrderModelFormForm(request.POST)
    if not form.is_valid():
        return render(request, 'form.html', {'form': form})

    # 获取 url 和 count
    video_url = form.cleaned_data['url']
    count = form.cleaned_data['count']

    # 0.获取原播放
    status, old_view_count = get_old_view_count(video_url)
    if not status:
        form.add_error("url", "视频原播放获取失败")
        return render(request, 'form.html', {'form': form})

    # 1. 根据数量获取单价，计算出原价
    for idx in range(len(form.price_count_list) - 1, -1, -1):
        limit_count, _, unit_price = form.price_count_list[idx]
        if count >= limit_count:
            break

    total_price = unit_price * count

    # 2.当前客户所处的级别，根据级别计算折扣后的价格
    try:
        with transaction.atomic():
            customer_obj = models.Customer.objects.filter(id=request.wl_user.id).select_for_update().first()
            real_price = total_price * customer_obj.level.percent / 100

            # 3. 判断账户的余额够不够
            if customer_obj.balance < real_price:
                form.add_error("count", "余额不足")
                return render(request, 'form.html', {'form': form})

            # 4.创建订单
            # 4.1生成订单号
            while True:
                random_number = random.randint(10000000, 99999999)
                ctime = datetime.datetime.now().strftime("%Y%m%d%H%M%S%f")
                oid = f"{ctime}{random_number}"
                exists = models.Order.objects.filter(oid=oid).exists()
                if exists:
                    continue
                break
            # 4.2爬虫，发送网络请求获取原播放
            # 在 0 处展示

            # 4.3客户的id 等于当前登录用户的id
            form.instance.oid = oid
            form.instance.price = total_price
            form.instance.real_price = real_price
            form.instance.old_view_count = old_view_count
            form.instance.customer_id = request.wl_user.id
            form.save()

            # 5.账号扣款
            models.Customer.objects.filter(id=request.wl_user.id).update(balance=F("balance") - real_price)

            # 6.生成交易记录
            models.TransationRecord.objects.create(
                charge_type=3,
                customer_id=request.wl_user.id,
                amount=real_price,
                order_oid=oid,
            )

            # 7.写入队列
            conn = get_redis_connection("default")
            conn.lpush(settings.QUEUE_TASK_NAME, oid)
            # 注意：要考虑事务和锁
    except Exception as ex:
        form.add_error("count", "创建订单失败！")
        return render(request, 'form.html', {'form': form})

    return redirect("/my/order/list/")


def my_order_cancle(request, pk):
    """撤单"""
    # 0.获取订单信息，做校验
    order_object = models.Order.objects.filter(id=pk, active=1, status=1, customer_id=request.wl_user.id).first()
    if not order_object:
        messages.add_message(request, settings.MESSAGE_DANGER_TAG, "订单不存在")
        return redirect("/my/order/list/")
    try:
        with transaction.atomic():
            customer_obj = models.Customer.objects.filter(id=request.wl_user.id).select_for_update().first()

            # 1.订单状态变化为 (5,"已撤单")
            models.Order.objects.filter(id=pk, active=1, status=1, customer=request.wl_user.id).update(status=5)

            # 2.归还余额
            models.Customer.objects.filter(id=request.wl_user.id).update(balance=F("balance") + order_object.real_price)

            # 3.生成交易记录
            models.TransationRecord.objects.create(
                charge_type=5,
                customer_id=request.wl_user.id,
                amount=order_object.real_price,
                order_oid=order_object.oid,
            )

            # 4.撤单成功
            messages.add_message(request, messages.SUCCESS, "撤单成功")
            return redirect("/my/order/list/")

    except Exception as e:

        # 5.撤单失败
        messages.add_message(request, settings.MESSAGE_DANGER_TAG, "撤单失败")
        return redirect("/my/order/list/")
